﻿using BCCommon;
using BCData.OA.BusinessFlowModel.BusinessFlowModel;
using BCData.OA.BusinessFlowModel.BusinessFlowStepModel;
using BCData.OA.PageBusiness.PageBusinessConfig;
using BCData.OA.PageBusiness.PageBusinessMappingDepartment;
using BCDto.OA.BusinessFlowModel.BusinessFlowStepModel;
using BCEntity.OA.BusinessFlowModel.BusinessFlowStepModel;
using BCEntity.OA.PageBusiness.PageBusinessConfig;
using BCEntity.OA.PageBusiness.PageBusinessMappingDepartment;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.OA.BusinessFlowModel.BusinessFlowStepModel
{
    public class BusinessFlowStepModelService : IBusinessFlowStepModelService
    {
        private readonly IBusinessFlowModelData businessFlowModelData;
        private readonly IBusinessFlowStepModelData businessFlowStepModelData;
        private readonly IPageBusinessConfigData pageBusinessConfigData;
        private readonly IPageBusinessMappingDepartmentData pageBusinessMappingDepartmentData;
        public BusinessFlowStepModelService(IBusinessFlowModelData businessFlowModelData, IBusinessFlowStepModelData businessFlowStepModelData, IPageBusinessConfigData pageBusinessConfigData,
            IPageBusinessMappingDepartmentData pageBusinessMappingDepartmentData)
        {
            this.businessFlowModelData = businessFlowModelData;
            this.businessFlowStepModelData = businessFlowStepModelData;
            this.pageBusinessConfigData = pageBusinessConfigData;
            this.pageBusinessMappingDepartmentData = pageBusinessMappingDepartmentData;
        }

        public bool Exists(long businessFlowStepModelId)
        {
            return this.businessFlowStepModelData.Exists(businessFlowStepModelId).GetAwaiter().GetResult();
        }

        public bool Exists(string businessFlowStepModelCode)
        {
            return this.businessFlowStepModelData.Exists(businessFlowStepModelCode).GetAwaiter().GetResult();
        }

        public BusinessFlowStepModelDto Add(BusinessFlowStepModelRequestDto requestDto)
        {
            if (this.businessFlowStepModelData.Exists(requestDto.BusinessFlowStepModelCode).GetAwaiter().GetResult())
            {
                throw new ArgumentException("业务流步骤模型编码已存在");
            }

            if (this.businessFlowStepModelData.Exists(requestDto.BusinessFlowModelId, requestDto.Step).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此业务流模型步骤信息已存在");
            }
            PageBusinessConfigEntity pageBusinessConfigEntity = null;
            IEnumerable<PageBusinessMappingDepartmentEntity> pageBusinessMappingEntities = null;
            if (requestDto.PageBusinessConfigId.HasValue)
            {
                pageBusinessConfigEntity = this.pageBusinessConfigData.GetEntity(requestDto.PageBusinessConfigId.Value).GetAwaiter().GetResult();
                if (pageBusinessConfigEntity == null)
                {
                    throw new ArgumentException("此业务配置不存在");
                }
                pageBusinessMappingEntities = this.pageBusinessMappingDepartmentData.GetEntitiesByPageBusinessConfigId(requestDto.PageBusinessConfigId.Value).GetAwaiter().GetResult();
                if (pageBusinessMappingEntities.Any(p => p.BusinessFlowModelId == requestDto.BusinessFlowModelId))
                {
                    throw new ArgumentException("此页面业务与此业务流模型存在死循环引用，无法完成配置。请选择其他页面业务配置信息");
                }
            }
            var businessFlowModelEntity = this.businessFlowModelData.GetEntity(requestDto.BusinessFlowModelId).GetAwaiter().GetResult();
            if (businessFlowModelEntity == null)
            {
                throw new ArgumentException("此业务流模型信息不存在");
            }

            var entity = requestDto.As<BusinessFlowStepModelEntity>();
            if (pageBusinessConfigEntity != null)
            {
                entity.PageBusinessCode = pageBusinessConfigEntity.PageBusinessCode;
                entity.PageBusinessName = pageBusinessConfigEntity.PageBusinessName;
            }

            entity.BusinessFlowModelId = businessFlowModelEntity.BusinessFlowModelId;
            entity.BusinessFlowModelName = businessFlowModelEntity.BusinessFlowModelName;
            entity.BusinessFlowModelCode = businessFlowModelEntity.BusinessFlowModelCode;
            return this.businessFlowStepModelData.Add(entity).GetAwaiter().GetResult().As<BusinessFlowStepModelDto>();
        }
        public BusinessFlowStepModelDto Update(BusinessFlowStepModelPutDto putDto)
        {
            if (!this.Exists(putDto.BusinessFlowStepModelId))
            {
                throw new ArgumentException("此记录不存在");
            }
            var oldEntity = this.businessFlowStepModelData.GetEntity(putDto.BusinessFlowStepModelId).GetAwaiter().GetResult();
            if (oldEntity.BusinessFlowStepModelCode != putDto.BusinessFlowStepModelCode)
            {
                if (this.businessFlowStepModelData.Exists(putDto.BusinessFlowStepModelCode).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("OA系统业务流步骤模型编码已存在");
                }
            }
            if (oldEntity.BusinessFlowModelId != putDto.BusinessFlowModelId || oldEntity.Step != putDto.Step)
            {
                if (this.businessFlowStepModelData.Exists(putDto.BusinessFlowModelId, putDto.Step).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("此业务流模型步骤信息已存在");
                }
            }

            PageBusinessConfigEntity pageBusinessConfigEntity = null;
            IEnumerable<PageBusinessMappingDepartmentEntity> pageBusinessMappingEntities = null;
            if (putDto.PageBusinessConfigId.HasValue)
            {
                pageBusinessConfigEntity = this.pageBusinessConfigData.GetEntity(putDto.PageBusinessConfigId.Value).GetAwaiter().GetResult();
                if (pageBusinessConfigEntity == null)
                {
                    throw new ArgumentException("此业务配置不存在");
                }
                pageBusinessMappingEntities = this.pageBusinessMappingDepartmentData.GetEntitiesByPageBusinessConfigId(putDto.PageBusinessConfigId.Value).GetAwaiter().GetResult();
                if (pageBusinessMappingEntities.Any(p => p.BusinessFlowModelId == putDto.BusinessFlowModelId))
                {
                    throw new ArgumentException("此页面业务与此业务流模型存在死循环引用，无法完成配置。请选择其他页面业务配置信息");
                }
            }
            var businessFlowModelEntity = this.businessFlowModelData.GetEntity(putDto.BusinessFlowModelId).GetAwaiter().GetResult();
            if (businessFlowModelEntity == null)
            {
                throw new ArgumentException("此业务流模型信息不存在");
            }

            var entity = putDto.As<BusinessFlowStepModelEntity>();
            if (pageBusinessConfigEntity != null)
            {
                entity.PageBusinessCode = pageBusinessConfigEntity.PageBusinessCode;
                entity.PageBusinessName = pageBusinessConfigEntity.PageBusinessName;
            }
            entity.BusinessFlowModelId = businessFlowModelEntity.BusinessFlowModelId;
            entity.BusinessFlowModelName = businessFlowModelEntity.BusinessFlowModelName;
            entity.BusinessFlowModelCode = businessFlowModelEntity.BusinessFlowModelCode;
            return this.businessFlowStepModelData.Update(entity).GetAwaiter().GetResult().As<BusinessFlowStepModelDto>();
        }

        public bool Delete(long businessFlowStepModelId)
        {
            if (!this.Exists(businessFlowStepModelId))
            {
                throw new ArgumentException("此记录不存在");
            }

            return this.businessFlowStepModelData.Delete(businessFlowStepModelId).GetAwaiter().GetResult();
        }

        public BusinessFlowStepModelDto GetEntity(long businessFlowStepModelId)
        {
            return this.businessFlowStepModelData.GetEntity(businessFlowStepModelId).GetAwaiter().GetResult().As<BusinessFlowStepModelDto>();
        }

        public IEnumerable<BusinessFlowStepModelDto> GetList(long businessFlowModelId)
        {
            return this.businessFlowStepModelData.GetList(businessFlowModelId).GetAwaiter().GetResult().As<IEnumerable<BusinessFlowStepModelDto>>();
        }

        public PageableList<BusinessFlowStepModelDto> Query(long? businessFlowModelId, string businessFlowStepModelName, string businessFlowModelName, DateTime? start, DateTime? end, int pageIndex, int pageSize)
        {
            var (list, count) = this.businessFlowStepModelData.Query(businessFlowModelId, businessFlowStepModelName, businessFlowModelName, start, end, pageIndex, pageSize).GetAwaiter().GetResult();

            return new PageableList<BusinessFlowStepModelDto>
            {
                Items = list.As<IEnumerable<BusinessFlowStepModelDto>>(),
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize
            };
        }
    }
}
